package com.common.frame.base

import android.content.pm.ActivityInfo
import android.graphics.Color
import android.os.Bundle
import android.view.View
import android.view.Window
import android.view.WindowManager
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.activity.ComponentActivity
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.constraintlayout.widget.Group
import androidx.core.view.isVisible
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelLazy
import androidx.lifecycle.ViewModelProvider
import com.common.frame.BR
import com.common.frame.R
import com.common.frame.bean.MessageEvent
import com.common.frame.bean.TipsEvent
import com.common.frame.bean.ToastBean
import com.common.frame.listener.BindEventListener
import com.common.frame.utils.Res
import com.common.frame.utils.StatusBarUtil
import com.common.frame.widget.CustomToast
import com.common.frame.widget.LoadingDialog
import com.common.frame.widget.StatusBarHeightView
import com.common.frame.widget.TipsDialog
import com.hjq.toast.ToastUtils
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.lang.reflect.ParameterizedType

abstract class BaseActivity<VM : BaseViewModel, VB : ViewDataBinding> : AppCompatActivity(),
    View.OnClickListener {

    lateinit var binding: VB
    val viewModel by initViewModel()
    var titleBarView: View? = null

    private var loadingDialog: LoadingDialog? = null
    private var customToast: CustomToast? = null
    private var tipsDialog: TipsDialog? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)

  /*      if (forcePortrait()) {
            try {
                requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
            } catch (e: Exception) {
            }
        }*/
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_base)
        StatusBarUtil.setTranslucentStatus(this)
        StatusBarUtil.setStatusBarDarkTheme(this, true)

        if (this.javaClass.isAnnotationPresent(BindEventListener::class.java) && !EventBus.getDefault()
                .isRegistered(this)
        ) {
            EventBus.getDefault().register(this)
        }

        val container = findViewById<FrameLayout>(R.id.layout_container)
        if (layoutId() != 0) {
            binding = DataBindingUtil.inflate(layoutInflater, layoutId(), container, true)
        }
        registerViewModelChange()

        binding.setVariable(BR.viewModel, viewModel)
        binding.setVariable(BR.listener, this)
        binding.lifecycleOwner = this


        statusView.isVisible = fitsSystemWindows()
        titleBar.isVisible = showTitleBar()

        findViewById<View>(R.id.btn_back)?.setOnClickListener { finish() }

        if (containerIsTop()) {
            setLayoutContainerIsTop()
        }
        initData()
        initView()
        initObserve()
        initListener()


    }

    abstract fun layoutId(): Int

    abstract fun initData()

    abstract fun initView()

    open fun initVariableId(): Int = 0

    open fun initListener() {}

    open fun initObserve() {

    }

    override fun onClick(v: View) {

    }

    /**
     * 是否强制竖屏
     */
    open fun forcePortrait(): Boolean = true

    /**
     * 是沉浸式  true:不沉浸式 false：沉浸式
     */
    open fun fitsSystemWindows(): Boolean = true

    open fun showTitleBar(): Boolean = true

    open fun containerIsTop(): Boolean = false

    private fun ComponentActivity.initViewModel(): Lazy<VM> {
        val factoryPromise = {
            defaultViewModelProviderFactory
        }
        return ViewModelLazy(
            getViewModelType().kotlin,
            { viewModelStore },
            factoryPromise,
            { defaultViewModelCreationExtras })
    }

    open fun getViewModelType(): Class<VM> {
        val modelClass: Class<VM>
        val type = javaClass.genericSuperclass
        modelClass = if (type is ParameterizedType) {
            type.actualTypeArguments[0] as Class<VM>
        } else {
            //如果没有指定泛型参数，则默认使用BaseViewModel
            BaseViewModel::class.java as Class<VM>
        }
        return modelClass
    }


    private fun registerViewModelChange() {
        viewModel.showLoadingDialog.observe(this) { showLoading(it) }
        viewModel.dismissLoadingDialog.observe(this) { dismissLoading() }
        viewModel.toastEvent.observe(this) {
            ToastUtils.show(it)
        }
        viewModel.dataEvent.observe(this) {
            handleEvent(it.action, it.result)
        }
        viewModel.customToastEvent.observe(this) {
            showToast(it)
        }
        viewModel.tipsEvent.observe(this) {
            showTips(it)
        }
        viewModel.finishEvent.observe(this) {
            finish()
        }
    }


    open fun handleEvent(action: String, result: Any) {}

    fun setToolbarVisible(b: Boolean) {
        titleBar.isVisible = b
        lineView.isVisible = b


    }

    fun setToolbarTitle(title: String?) {
        findViewById<TextView>(R.id.tv_title)?.text = title
    }

    fun setToolbarTitle(resId: Int) {
        findViewById<TextView>(R.id.tv_title)?.text = Res.getString(resId)
    }

    fun setTitleBarBgColor(colorId: Int) {
        findViewById<View>(R.id.view_bg)?.setBackgroundColor(Res.getColor(colorId))

    }

    fun hideToolbar() {
        setStatusViewVisible(false)
        setToolbarVisible(false)
    }

    open fun hideStatusBar(status: Boolean) {
        if (status) {
            window.setFlags(
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN
            );
        }
    }

    fun setRootBg(resId: Int) {
        findViewById<View>(R.id.view_bg)?.setBackgroundColor(Color.TRANSPARENT)
        findViewById<View>(R.id.layout_root)?.setBackgroundResource(resId)
    }

    fun setWhiteTitleBar() {
        findViewById<View>(R.id.view_bg)?.setBackgroundColor(Color.WHITE)
        lineView.visibility = View.VISIBLE
        findViewById<ImageView>(R.id.btn_back)?.setImageResource(R.mipmap.ic_back_black)
        findViewById<TextView>(R.id.tv_title)?.setTextColor(Res.getColor(R.color.color_333333))
    }

    fun setThemeTitleBar() {
        findViewById<ImageView>(R.id.btn_back)?.setImageResource(R.mipmap.ic_back_white)
        findViewById<TextView>(R.id.tv_title)?.setTextColor(Res.getColor(R.color.white))
        setTitleBarBgColor(R.color.theme)
        lineView.visibility = View.GONE
    }

    fun setStatusViewVisible(b: Boolean) {
        statusView.visibility = if (b) View.VISIBLE else View.GONE
    }

    private val titleBar: Group
        get() = findViewById(R.id.layout_title)

    private val statusView: StatusBarHeightView
        get() = findViewById(R.id.status_view)


    private val lineView: View
        get() = findViewById(R.id.view_line)

    val layoutRoot: ConstraintLayout
        get() = findViewById(R.id.layout_root)

    fun getBackView(): ImageView = findViewById(R.id.btn_back)

    fun getRightView(): ImageView = findViewById(R.id.iv_right)

    fun getRightButton(): TextView = findViewById(R.id.btn_right)

    private fun setLayoutContainerIsTop() {
        val set = ConstraintSet()
        set.clone(layoutRoot)
        set.connect(
            R.id.layout_container,
            ConstraintSet.TOP,
            ConstraintSet.PARENT_ID,
            ConstraintSet.TOP
        )
        set.applyTo(layoutRoot)
    }

    override fun onDestroy() {

        if (this.javaClass.isAnnotationPresent(BindEventListener::class.java) && EventBus.getDefault()
                .isRegistered(this)
        ) {
            EventBus.getDefault().unregister(this)
        }
        super.onDestroy()

    }


    fun showLoading(text: String = "加载中...") {
        loadingDialog ?: let {
            loadingDialog = LoadingDialog(this)
        }
        loadingDialog?.show()
        loadingDialog?.setTips(text)
    }

    fun dismissLoading() {
        loadingDialog?.let {
            if (it.isShowing) it.dismiss()
        }
    }

    fun showToast(item: ToastBean) {
        customToast ?: let {
            customToast = CustomToast(this)
        }
        customToast?.setText(item.msg)
        customToast?.showToast(item.duration)
    }

    fun showTips(event: TipsEvent) {
        if (!this.isFinishing) {
            tipsDialog ?: let {
                tipsDialog = TipsDialog(this).apply {
                    listener = {
                        onTipsEvent(it)
                    }
                }
            }
            tipsDialog?.show(event)
        }
    }

    open fun onTipsEvent(event: TipsEvent) {

    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEvent(msg: MessageEvent) {
        onReceiveEvent(msg)
    }


    open fun onReceiveEvent(event: MessageEvent) {

    }


}